package com.ruihu.admin.module.business.tasknode.manager;

import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.io.IORuntimeException;
import cn.hutool.http.HttpUtil;
import com.alibaba.fastjson.JSON;
import com.ruihu.admin.common.constant.JudgeEnum;
import com.ruihu.admin.common.constant.SuccessEnum;
import com.ruihu.admin.common.domain.ResponseDTO;
import com.ruihu.admin.common.domain.RetDTO;
import com.ruihu.admin.constant.CommonConst;
import com.ruihu.admin.module.business.log.interfacelog.constant.InterfaceModuleEnum;
import com.ruihu.admin.module.business.log.interfacelog.dao.ElectricUpdateMessageQueueDao;
import com.ruihu.admin.module.business.log.interfacelog.dao.InterfaceLogDao;
import com.ruihu.admin.module.business.log.interfacelog.domain.entity.ElectricUpdateMessageQueueEntity;
import com.ruihu.admin.module.business.log.interfacelog.domain.entity.InterfaceLogEntity;
import com.ruihu.admin.module.business.task.constant.TaskResponseCodeConst;
import com.ruihu.admin.module.business.task.domain.entity.SubTaskEntity;
import com.ruihu.admin.util.RequestTokenUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.io.IOException;
import java.net.ConnectException;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

@Service
@Slf4j
public class InterfaceManager {

    @Value("${ai.interface.url}")
    private String aiInterfaceUrl;

    @Autowired
    private InterfaceLogDao interfaceLogDao;

    @Autowired
    private ElectricUpdateMessageQueueDao electricUpdateMessageQueueDao;

    /**
     * 发送新增电芯编码消息到AI系统
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    public ResponseDTO<String> sendAddElectricCoreMessageToAI(SubTaskEntity subTaskEntity) {
        InterfaceLogEntity interfaceLogEntity = this.createInterfaceLogEntity(subTaskEntity, 0, InterfaceModuleEnum.SEND_ADD_MSG_TO_AI);
        try {
            RetDTO retDTO = this.invokeInterface(interfaceLogEntity.getParam());
            if (JudgeEnum.YES.getValue().equals(retDTO.getIsSuccess())) {
                interfaceLogEntity.setResult(JudgeEnum.YES.getValue());

                // 新增消息发送成功后则往清空队列中放入待清空电芯编码
                ElectricUpdateMessageQueueEntity entity = new ElectricUpdateMessageQueueEntity();
                entity.setElectricCoreCode(subTaskEntity.getElectricCoreCode());
                this.electricUpdateMessageQueueDao.insert(entity);
            } else {
                interfaceLogEntity.setResult(JudgeEnum.NO.getValue());
                interfaceLogEntity.setFailReason(retDTO.getMsg());
            }
            interfaceLogEntity.setStatus(JudgeEnum.YES.getValue().toString());
            interfaceLogEntity.setCompletionTime(new Date());
            this.interfaceLogDao.insert(interfaceLogEntity);

            return ResponseDTO.succData(retDTO.getMsg());
        } catch (IORuntimeException ex) {
            log.error("Send Message to AI error", ex);

            interfaceLogEntity.setResult(JudgeEnum.NO.getValue());
            interfaceLogEntity.setFailReason(ex.getMessage());
            interfaceLogEntity.setStatus(JudgeEnum.YES.getValue().toString());
            interfaceLogEntity.setCompletionTime(new Date());
            this.interfaceLogDao.insert(interfaceLogEntity);
        }

        return ResponseDTO.wrap(TaskResponseCodeConst.AI_INVOKE_FAIL);
    }

    /**
     * 发送清除电芯编码消息到AI系统
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    public ResponseDTO<String> sendClearElectricCoreMessageToAI(SubTaskEntity subTaskEntity, ElectricUpdateMessageQueueEntity updateMessageQueueEntity) {
        InterfaceLogEntity interfaceLogEntity = this.createInterfaceLogEntity(subTaskEntity, 1, InterfaceModuleEnum.SEND_UPDATE_MSG_TO_AI);
        try {
            RetDTO retDTO = this.invokeInterface(interfaceLogEntity.getParam());
            if (JudgeEnum.YES.getValue().equals(retDTO.getIsSuccess())) {
                interfaceLogEntity.setResult(JudgeEnum.YES.getValue());
                // 清空成功后，将电芯编码从待清除列表中移出
                this.electricUpdateMessageQueueDao.deleteById(updateMessageQueueEntity.getId());
            } else {
                interfaceLogEntity.setResult(JudgeEnum.NO.getValue());
                interfaceLogEntity.setFailReason(retDTO.getMsg());
            }
            interfaceLogEntity.setStatus(JudgeEnum.YES.getValue().toString());
            interfaceLogEntity.setCompletionTime(new Date());
            this.interfaceLogDao.insert(interfaceLogEntity);

            return ResponseDTO.succData(retDTO.getMsg());
        } catch (IORuntimeException ex) {
            log.error("Send Message to AI error", ex);

            interfaceLogEntity.setResult(JudgeEnum.NO.getValue());
            interfaceLogEntity.setFailReason(ex.getMessage());
            interfaceLogEntity.setStatus(JudgeEnum.YES.getValue().toString());
            interfaceLogEntity.setCompletionTime(new Date());
            this.interfaceLogDao.insert(interfaceLogEntity);
        }

        return ResponseDTO.wrap(TaskResponseCodeConst.AI_INVOKE_FAIL);
    }

    private InterfaceLogEntity createInterfaceLogEntity(SubTaskEntity subTaskEntity, Integer isChange, InterfaceModuleEnum interfaceModuleEnum) {
        String currentDateTime = DateUtil.format(new Date(), DatePattern.NORM_DATETIME_PATTERN);
        Map<String, Object> param = new HashMap<>();
        param.put("isChange", isChange);
        param.put("serialNumber", subTaskEntity.getElectricCoreCode());
        param.put("createTime", currentDateTime);
        InterfaceLogEntity interfaceLogEntity = new InterfaceLogEntity();
        interfaceLogEntity.setSubTaskId(subTaskEntity.getId());
        interfaceLogEntity.setMainTaskId(subTaskEntity.getMainTaskId());
        interfaceLogEntity.setElectricCoreCode(subTaskEntity.getElectricCoreCode());
        interfaceLogEntity.setModule(interfaceModuleEnum.getValue());
        interfaceLogEntity.setContent(interfaceModuleEnum.getDesc());
        interfaceLogEntity.setParam(param);
        interfaceLogEntity.setCreateTime(new Date());
        interfaceLogEntity.setCreateBy(RequestTokenUtil.getRequestUser().getRequestUserId());
        interfaceLogEntity.setRevision(CommonConst.DEFAULT_OPTI_LOCK_REVISION);

        return interfaceLogEntity;
    }

    private RetDTO invokeInterface(Map<String, Object> param) {
        RetDTO retDTO;
        try {
            String msgBody = JSON.toJSONString(param);
            log.info("Message send to AI System >>> {}", msgBody);
            String responseStr = HttpUtil.post(this.aiInterfaceUrl, msgBody, 1000 * 30);
            log.info("Message returned by AI System >>> {}", responseStr);
            retDTO = JSON.parseObject(responseStr, RetDTO.class);
            retDTO.setIsSuccess(JudgeEnum.YES.getValue());
        } catch (Exception ex) {
            log.error(ex.getMessage(), ex);
            retDTO = new RetDTO();
            retDTO.setIsSuccess(JudgeEnum.NO.getValue());
            retDTO.setMsg(ex.getMessage());
        }
        return retDTO;
    }
}
